<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>待办事项列表-eventbus练习</title>
    <link rel="stylesheet" href="./lib/bulma.min.css">
    <style>
            .completed-class {
              background: #eaeaea;
              text-decoration: line-through;
            }
            .content {
              overflow: hidden;
              text-overflow: ellipsis;
              white-space: nowrap;
            }
          </style>
</head>
<body>
    <div id="app">
        <todo-header>
            <template #title>
                <h1 class="title">TodoList</h1>
            </template>
        </todo-header>
        <todo-input @add="addTodoItem"></todo-input>
        <todo-list :list="todos"></todo-list>
    </div>

<script src="./lib/vue.js"></script>
<script>
  // 定义一个全局的 Vue 实例
  const eventBus = new Vue()

// TodoHeader组件的选项对象
const todoHeaderOptions = {
  template: `
    <section class="hero is-primary">
      <div class="hero-body">
        <slot name="title">
          <p class="title">
            待办事项列表
          </p>
        </slot>
        <slot name="subtitle">
          <p class="subtitle">
            今日事今日毕！
          </p>
        </slot>
      </div>
    </section>
  `
}

// TodoInput组件的选项对象
const todoInputOptions = {
  template: `
    <div class="field is-grouped container" :style="{marginTop: '12px'}">
      <p class="control is-expanded">
        <input
          class="input"
          type="text"
          placeholder="请输入新待办事项"
          v-model.trim="inputValue"
          @keydown.enter="handleAdd"
          ref="inputRef"
        >
      </p>
      <p class="control">
        <a href="/" class="button is-primary" @click.prevent="handleAdd">
          添加
        </a>
      </p>
    </div>
  `,
  data() { // 组件中的 data 必须是函数结构，因为如果把data设计为普通函数，则多个组件实例都引用到的是一个对象，当其中某一个组件实例修改数据后，其他组件实例会相应受影响，与实际需求有差异。
    return {
      inputValue: ''//文本框清空
    }
  },
  methods: {//方法
    handleAdd() {//处理程序
      // 文本框自动获得焦点
      this.$refs.inputRef.focus()  //ref获得文本DOM元素，实现焦点

      if (this.inputValue.length === 0) {
        return
      }

      // 将输入框中的文本传递给父组件
      // 使用 this.$emit() 触发在父组件中绑定的事件
      this.$emit('add', this.inputValue)

      // 清空文本框
      this.inputValue = ''
    }
  }
}

// TodoItem
const todoItemOptions = {
  template: `
    <div class="card">
      <div class="card-content" :class="{'completed-class': completed}">
        <div class="content" :title="title">
          {{ title }}
        </div>
      </div>
      <footer class="card-footer">
        <a href="/" class="card-footer-item" @click.prevent="handleToggle">{{ completed ? '未' : '已' }}完成</a>
        <a href="/" class="card-footer-item" @click.prevent="handleRemove">删除</a>
      </footer>
    </div>
  `,
  props: { // props 也可以使用对象，实现属性的验证
    id: Number,
    title: {
      type: String,
      default: '待办事项'
    },
    completed: {
      type: Boolean,
      required: true
    }
  },
  methods: {
    handleRemove() {
      // 调用 eventBus 的 $emit 方法，触发事件，传递待删除的 id
      eventBus.$emit('remove', this.id)
    },
    handleToggle() {
      eventBus.$emit('toggle', this.id)
    }
  }
}

// TodoList
const todoListOptions = {
  template: `
    <div class="container">
      <div class="tabs">
        <ul>
          <li :class="{'is-active': tabType === 'all'}"><a href="/" @click.prevent="toggleTabs('all')">所有({{list.length}})</a></li>
          <li :class="{'is-active': tabType === 'completed'}"><a href="/" @click.prevent="toggleTabs('completed')">已完成({{completedTodos.length}})</a></li>
          <li :class="{'is-active': tabType === 'uncompleted'}"><a href="/" @click.prevent="toggleTabs('uncompleted')">未完成({{uncompletedTodos.length}})</a></li>
        </ul>
      </div>

      <div class="columns is-multiline">
        <div class="column is-full" v-if="currentTodos.length === 0">
          当前待办事项列表为空
        </div>
        <template v-else>
          <div
            class="column is-one-quarter"
            v-for="todo in currentTodos"
          >
            <todo-item
              :id="todo.id"
              :title="todo.title"
              :completed="todo.completed"
            />
          </div>
        </template>
      </div>
    </div>
  `,
  components: { // 局部注册组件
    TodoItem: todoItemOptions
  },
  data() {
    return {
      tabType: 'all',
      currentTodos: []
    }
  },
  props: ['list'], // 声明当前组件可接收的属性
  computed: {
    completedTodos() {
      return this.list.filter(todo => todo.completed)
    },
    uncompletedTodos() {
      return this.list.filter(todo => !todo.completed)
    }
  },
  methods: {
    // 切换选项卡
    toggleTabs(type) {
      console.log("状态：", type)
      this.tabType = type
      this.setCurrentTodos()
    },
    // 根据选项卡选择，设置当前显示的待办事项
    setCurrentTodos() {
      switch(this.tabType) {
        case 'all':
          this.currentTodos = this.list
          break
        case 'completed':
          this.currentTodos = this.completedTodos
          break
        case 'uncompleted':
          this.currentTodos = this.uncompletedTodos
          break
      }
    }
  },
  watch: {
    list: {
      handler() {
        this.setCurrentTodos()
      },
      deep: true
    }
  }
}

// App
new Vue({
  el: '#app',
  components: { // 局部注册组件
    TodoHeader: todoHeaderOptions,
    TodoInput: todoInputOptions,
    TodoList: todoListOptions
  },
  data: {
    todos: [
      {
        id: 1,
        title: '复习HTML',
        completed: true
      },
      {
        id: 2,
        title: '复习JavaScript',
        completed: false
      }
    ]
  },
  // 组件实例被创建后执行 created 方法
  created() {
    // 绑定事件，接收待办事项的 id，删除数组中对应的待办事项
    eventBus.$on('remove', this.removeTodoItem)
    // 绑定事件，接收待办事项的 id，修改数组中对应的待办事项状态
    eventBus.$on('toggle', this.toggleTodoItem)
    // 获取网络接口中的待办事项数据
    fetch('https://jsonplaceholder.typicode.com/todos?userId=1')
      .then(res => res.json())
      .then(data => {
        this.todos = data
      })
  },
  methods: {
    // 添加新待办事项
    addTodoItem(title) {
      this.todos.push({
        id: Math.random(),
        title,
        completed: false
      })
    },
    // 修改待办事项完成状态
    toggleTodoItem(id) {
      this.todos.forEach(todo => {
        if (todo.id === id) {
          todo.completed = !todo.completed
        }
      })
    },
    // 删除待办事项
    removeTodoItem(id) {
      this.todos = this.todos.filter(todo => todo.id !== id)
    }
  }
})




</script>

</body>
</html>